package com.mangix.scheduler;

import com.mangix.core.Finger;
import com.mangix.core.MangixMonitor;
import com.mangix.core.MangixNode;
import com.mangix.db.MangixDB;
import com.mangix.files.MangixFiles;
import com.mangix.http.MangixHttpClient;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.util.StringContentProvider;
import org.json.simple.JSONValue;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Ahan on 2014/8/6.
 */
public class MangixReporter extends Thread{

    private MangixNode localNode;

    public MangixReporter(MangixNode localNode){
        this.localNode = localNode;
        this.setName("Mangix Reporter - " + localNode.toString());
    }

    @Override
    public void run() {
        while(true) {
            try {
                Thread.sleep(1000 * 60);
            } catch (InterruptedException e) {
                break;
            }
            try{
                report();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void report(){
        MangixMonitor monitor = this.localNode.getMonitor();
        MangixDB mangixDB = this.localNode.getDB();
        if (monitor == null) {
            System.out.println("Node " + localNode.toString() + " begins to report, but there is not a monitor");
            return;
        }
        Map obj = new LinkedHashMap();
        obj.put("hostname", this.localNode.getHostName());
        obj.put("port", this.localNode.getPort());
        MangixNode processor = mangixDB.getPredecessor();
        if (processor != null) {
            Map processorObj = new LinkedHashMap();
            processorObj.put("hostname", processor.getHostName());
            processorObj.put("port", processor.getPort());
            obj.put("processor", processorObj);
        }
        MangixNode successor = mangixDB.getSuccessor();
        if (successor != null) {
            Map successorObj = new LinkedHashMap();
            successorObj.put("hostname", successor.getHostName());
            successorObj.put("port", successor.getPort());
            obj.put("successor", successorObj);
        }
        Finger[] fingerTable = mangixDB.getFingerTable();
        List fingers = new ArrayList();
        for (int i = 0; i < fingerTable.length; i++) {
            Map finger = new LinkedHashMap();
            finger.put("start", new Long(fingerTable[i].start));
            if (fingerTable[i].node != null) {
                finger.put("hostname", fingerTable[i].node.getHostName());
                finger.put("port", fingerTable[i].node.getPort());
            }
            fingers.add(finger);
        }
        obj.put("finger_table", fingers);
        MangixFiles mangixFiles = this.localNode.getFiles();
        obj.put("object_num", mangixFiles.countObjectsNumber());
        try {
            long usedSpace = -1;
            usedSpace = mangixFiles.getUsedSpace();
            obj.put("used_space", usedSpace);
        } catch (Exception e) {
            e.printStackTrace();
        }
        obj.put("available_space", mangixFiles.getTotalAvailableSpace());
        String jsonText = JSONValue.toJSONString(obj);
        try {
            MangixHttpClient.put("http://" + monitor.getHostname() + ":" + monitor.getPort() + "/report", jsonText);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
